package com.youlu.campus.starter.web.config;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Maps;
import com.youlu.campus.common.base.QResult;
import com.youlu.campus.common.exception.BusinessException;
import com.youlu.campus.common.exception.WechatException;
import com.youlu.campus.common.model.GlobalErrorCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.multipart.MultipartException;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.security.auth.login.AccountException;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * 全局异常处理器
 *
 * @Description: GlobalExceptionHandler
 * @Date 2025/7/9
 * @author: su
 */
@Slf4j
@RestControllerAdvice
public class WebGlobalExceptionHandler {

    @ExceptionHandler(BusinessException.class)
    public QResult businessException(BusinessException e) {
        log.error("businessException code:{},", e.getError().getCode(), e.getMessage(), e);
        return QResult.fail(e.getError().getCode(), e.getMessage());
    }

    @ExceptionHandler(AccountException.class)
    public QResult accountException(AccountException e) {
        log.error("accountException e:{}", e);
        return QResult.fail(e.getMessage());
    }

    @ExceptionHandler(WechatException.class)
    public QResult wechatException(WechatException e) {
        log.info("wechatException 微信登陆Code重复：{}", e.getMessage(), e);
        return QResult.fail(e.getCode(), e.getMessage());

    }

    @ExceptionHandler(MultipartException.class)
    public QResult multipartException(MultipartException e) {
        log.error("multipartException 文件上传异常,异常信息", e);
        return QResult.fail(e.getMessage());
    }


    @ExceptionHandler(IllegalArgumentException.class)
    private Object illegalArgumentException(IllegalArgumentException e) {
        log.error("IllegalArgumentException 错误信息", e);
        return QResult.fail(e.getMessage());
    }

    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public QResult maxUploadSizeExceededException(MaxUploadSizeExceededException e) {
        log.error("MaxUploadSizeExceededException 上传文件过大,异常信息：{}", e.getMessage(), e);
        return QResult.fail("上传文件太大");
    }

    @ExceptionHandler(NoHandlerFoundException.class)
    public QResult noHandlerFoundException(NoHandlerFoundException ex) {
        log.error("NoHandlerFoundException 404 error requestUrl:{}, method:{}, exception:{}",
                ex.getRequestURL(), ex.getHttpMethod(), ex.getMessage(), ex);
        return QResult.fail(GlobalErrorCode.NOT_FOUND.getCode(), GlobalErrorCode.NOT_FOUND.getMessage());

    }

    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public QResult httpRequestMethodHandler(HttpServletRequest request,
                                            HttpRequestMethodNotSupportedException ex) {
        log.error("httpRequestMethodHandler 405 error requestUrl:{}, method:{}, exception:{}",
                request.getRequestURI(), ex.getMethod(), ex.getMessage(), ex);
        return QResult.fail(GlobalErrorCode.METHOD_NOT_ALLOWED.getCode(), GlobalErrorCode.METHOD_NOT_ALLOWED.getMessage());
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    private Object illegalParamsExceptionHandler(MethodArgumentNotValidException ex) {
        log.error("MethodArgumentNotValidException：{}", ex.getMessage(), ex);
        BindingResult bindingResult = ex.getBindingResult();
        Map<String, String> errors = Maps.newHashMapWithExpectedSize(bindingResult.getFieldErrorCount());
        for (FieldError fieldError : bindingResult.getFieldErrors()) {
            errors.put(fieldError.getField(), fieldError.getDefaultMessage());
            log.warn("---------> invalid request! fields ex:{}", JSON.toJSONString(errors));
            return QResult.fail(500, fieldError.getDefaultMessage());
        }
        return QResult.fail(500, "系统异常:请联系客服!");
    }

    @ExceptionHandler(Exception.class)
    public QResult exception(Exception e) {
        log.error("Exception 系统未知异常,异常信息:{}", e.getMessage(), e);
        return QResult.fail(e.getMessage());
    }


}
